package public

import (
	"sync"

	"golang.org/x/time/rate"
)

// 流量限制器管理器
var FlowLimiterHandler *FlowLimiter

type FlowLimiter struct {
	FlowLmiterMap   map[string]*FlowLimiterItem // 服务名 -> 限流器映射
	FlowLmiterSlice []*FlowLimiterItem          // 限流器列表（保持顺序）
	Locker          sync.RWMutex                // 读写锁
}

// 限流器
type FlowLimiterItem struct {
	ServiceName string        // 服务标识
	Limter      *rate.Limiter // 限流器实例
}

func NewFlowLimiter() *FlowLimiter {
	return &FlowLimiter{
		FlowLmiterMap:   map[string]*FlowLimiterItem{},
		FlowLmiterSlice: []*FlowLimiterItem{},
		Locker:          sync.RWMutex{},
	}
}

func init() {
	// 包加载时创建单例
	FlowLimiterHandler = NewFlowLimiter()
}

// 获取限流器
func (counter *FlowLimiter) GetLimiter(serverName string, qps float64) (*rate.Limiter, error) {
	// 1.先在切片中查找（遍历 O(n) ）优化点：查询map（O(1)）
	for _, item := range counter.FlowLmiterSlice {
		if item.ServiceName == serverName {
			return item.Limter, nil
		}
	}

	// 2.找不到则创建新的限流器
	newLimiter := rate.NewLimiter(rate.Limit(qps), int(qps*3))
	item := &FlowLimiterItem{
		ServiceName: serverName,
		Limter:      newLimiter,
	}

	// 3.添加到数据结构中
	counter.FlowLmiterSlice = append(counter.FlowLmiterSlice, item)
	counter.Locker.Lock()
	defer counter.Locker.Unlock()
	counter.FlowLmiterMap[serverName] = item
	return newLimiter, nil
}
